#-*- coding: utf-8 -*-

'''
像是一個介面，或是抽象的類別
'''
class Human( object ):
	count = 0
	
	# 宣告建構子
	def __init__( self, name, height, weight, sex = "male" ):
		self.name   = name
		self.height = height
		self.weight = weight
		self.sex	= sex
		
		print "Create a Human istance!"
	
	# 宣告實體方法

	def getName():
		return "Jaco"
	
	def sayHello( self ):
		print "Hi, my name is " + self.name + "."
		
	# 以下宣告抽象方法
		
	def eat( self ):
		assert False, "Not implement eat method!"
		
	def move( self ):
		assert False, "Not implement move method"
		
	def talk( self ):
		assert False, "Not implement talk method"
		
	def dance( self ):
		assert False, "Not implement dance method"
		
	pass
# end of class Human

'''
Human的實作類別
'''
class Man( Human ):
	def __init__( self, name, height, weight, sex = "male" ):
		Human.__init__( self, name, height, weight )
		print "Create a Man instance now!"
	
	# 以下實作抽象方法
	
	def eat( self ):
		print "Man eats"
		
	def move( self ):
		print "Man move"
		
	def dance( self ):
		return "Man dance"

	# 沒有實作talk抽象方法
	# def talk( self ):
		# print "Man talk"
		
	pass
# end of class Man

class Woman( Human ):
	def __init__( self, name, height, weight, sex = "female" ):
		Human.__init__( self, name, height, weight, sex )
		print "Create a Woman instance now!"
	
	# 以下實作抽象方法
	
	def eat( self ):
		print "Woman eats"
		
	def move( self ):
		print "Woman move"

	def talk( self ):
		print "Woman talk"
		
	def dance( self ):
		return "Sexy dance..."
		
	pass
# end of class Woman

'''
用來建構Human實體的工廠
'''
class HumanFactory():
	def createHuman( self, name, height, weight, sex ):
		result = None
		
		if sex == "male":
			result = Man( name, height, weight, sex )
			return result
		elif( sex == "female" ):
			result = Woman( name, height, weight, sex )
			return result
	
	pass
# end of class HumanFactory

man = Man( "Jack", 173.4, 64 )
man.eat()
man.move()

def jackTalk( self ):
	print self.name + ": Man talk"
	
man.talk = jackTalk		# 指派jackTalk函式給man實體，man實體時做自己的talk抽象方法
man.talk( man )
# Man.talk( man )		# 此行會拋出例外
man.sayHello()

print "\n=============================\n"

superman = Man( "John", 180, 78 )
# superman.talk()		# 此行會拋出例外，因為superman沒有實作抽象方法，並且呼叫了該抽象方法
superman.eat()
superman.move()
superman.sayHello()

print "\n=============================\n"

# 以下透過工廠產生Human類別的實體，再利用多型的呼叫

factory = HumanFactory()
human   = factory.createHuman( "ViVi", 176, 48, "female" )
dancing = human.dance()
print dancing

dancing = factory.createHuman( "Lenny", 162, 88, "male" ).dance()
print dancing